home *** CD-ROM | disk | FTP | other *** search
/ AppleScript - The Beta Release / AppleScript - The Beta Release.iso / Documentation / develop / Apple Event Objects and You / Apple Event Objects (code) / Windows.c < prev   
Encoding:
C/C++ Source or Header  |  1992-04-08  |  12.2 KB  |  436 lines  |  [TEXT/KAHL]

  1. /* File: Windows.c */
  2.  
  3. #include "ScriptScrap.h"
  4. #include "Prototypes.h"
  5.  
  6. #include "AERegistry.h"
  7.  
  8.  
  9. /* This routine gets called whenever the current selection gets changed and we        */
  10. /* need to draw a new entry or change the status area at the bottom of the window. */
  11. /* We'll use it to selectively invalidate only those areas which need re-drawing,  */
  12. /* which will prevent the "frame" portion from flickering.                           */
  13. void InvalidateWindow(WindowPtr whichWindow)
  14. {
  15.     Rect    r;
  16.     wiHand    info = (wiHand)GetWRefCon(whichWindow);
  17.     
  18.     SetPort(whichWindow);
  19.     r = (*info)->drawingArea;
  20.     InvalRect(&r);
  21.     r = (*info)->statusArea;
  22.     InvalRect(&r);
  23.     r = (*(*info)->selectionBar)->contrlRect;
  24.     InvalRect(&r);
  25. }
  26.  
  27.  
  28. void EntryAdded (WindowPtr whichWindow, short entryNum)
  29. {
  30.     /* This routine gets called whenever a new entry gets added to the */
  31.     /* scrapbook, and it updates the display appropriately.               */
  32.     wiHand    info = (wiHand)GetWRefCon(whichWindow);
  33.     
  34.     (*info)->numEntries += 1;
  35.     HiliteControl((*info)->selectionBar, 0);
  36.     SetCtlMax((*info)->selectionBar, (*info)->numEntries);
  37.     InvalidateWindow(whichWindow);
  38. }
  39.  
  40.  
  41. void EntryRemoved (WindowPtr whichWindow, short entryNum)
  42. {
  43.     /* This routine gets called whenever an entry is removed from the  */
  44.     /* scrapbook, and it updates the display appropriately.               */
  45.     wiHand    info = (wiHand)GetWRefCon(whichWindow);
  46.     
  47.     if ((*info)->numEntries > 0)
  48.         (*info)->numEntries -= 1;
  49.     if ((*info)->numEntries == 0)
  50.         HiliteControl((*info)->selectionBar, 255);
  51.     SetCtlMax((*info)->selectionBar, (*info)->numEntries);
  52.     if ((*info)->currEntryNum > (*info)->numEntries)
  53.         GoToEntry(whichWindow, (*info)->numEntries);
  54.     else
  55.         InvalidateWindow(whichWindow);
  56. }
  57.  
  58.  
  59. void GoToEntry (WindowPtr whichWindow, short entryNum)
  60. {
  61.     wiHand    info = (wiHand)GetWRefCon(whichWindow);
  62.     ResType    scratchType;
  63.     OSErr    err;
  64.     
  65.     if (entryNum < 1)
  66.         entryNum = 1;
  67.     else if (entryNum > (*info)->numEntries)
  68.         entryNum = (*info)->numEntries;
  69.     err = GetBestType(entryNum, &scratchType);    /* Get the default type for this entry */
  70.     if (err == noErr)
  71.         (*info)->currEntryType = scratchType;
  72.     SetCtlValue((*info)->selectionBar, entryNum);
  73.     (*info)->currEntryNum = entryNum;
  74.     InvalidateWindow(whichWindow);
  75.     DoUpdate(whichWindow);
  76. }
  77.  
  78.  
  79. OSErr NewScrapbookFile(FSSpec *theFile, Boolean *cancelled)
  80. {
  81.     /* This routine asks the user to create a new scrapbook file. If a file already */
  82.     /* exists, it replaced.                                                         */
  83.     /* Returns noErr if successful, and places an FSSpec into *theFile.             */
  84.     /* Returns errAEEventFailed if the user cancels, and sets *cancelled to TRUE.    */
  85.     /* Otherwise, returns any intermediate error codes that may occur.                */
  86.     
  87.     smapHand          theSmap;
  88.     StandardFileReply reply;
  89.     OSErr              err;
  90.     short              refNum = 0;
  91.     
  92.         err = MyInteractWithUser(true);    /* Make sure we're in front */
  93.         if (err != noErr) goto done;
  94.  
  95.         StandardPutFile("\p", "\pNew Scrapbook", &reply);
  96.         *cancelled = !reply.sfGood;
  97.         
  98.         if (reply.sfGood) {
  99.             *theFile = reply.sfFile;
  100.             /* Create the file so we can open it */
  101.             if (reply.sfReplacing) /* Get rid of the old file first */
  102.                 if (err = FSpDelete(theFile)) goto done;
  103.             FSpCreateResFile(theFile, 'scbk', 'scbk', reply.sfScript);
  104.             /* Open the file and create a blank SMAP resource in it */
  105.             refNum = FSpOpenResFile(theFile, fsRdWrPerm);
  106.             if ((err = ResError()) != noErr) goto done;
  107.             UseResFile(refNum);
  108.             theSmap = (void *) NewHandleClear(sizeof(smap));
  109.             if ((err = MemError()) != noErr) goto done;
  110.             AddResource((Handle)theSmap, 'SMAP', 0, "\p");
  111.             if ((err = ResError()) != noErr) goto done;
  112.             UpdateResFile(refNum);
  113.             if ((err = ResError()) != noErr) goto done;
  114.             
  115.         } else
  116.             err = errAEEventFailed;    /* The user cancelled */
  117.  
  118. done:
  119.     if (refNum > 0)
  120.         CloseResFile(refNum);
  121.  
  122.     return err;
  123. }
  124.  
  125.  
  126. OSErr NewDisplayWindow (const FSSpec *sourceFile)
  127. {
  128.     FSSpec        fileToOpen;
  129.     WindowPtr    newWindow = NULL;
  130.     wiHand        info      = NULL;
  131.     Ptr            storage      = NULL;
  132.     register OSErr err       = noErr;
  133.     short        refNum = 0;
  134.     short        numEntries;
  135.     Rect        scrollBarBounds,
  136.                 drawingArea, statusArea;
  137.     ControlHandle scrollBar;
  138.     ResType        scratchType;
  139.     Boolean        cancelled;
  140.     
  141.     if (sourceFile == NULL) {
  142.         /* If we haven't been given a file, then ask the user for one */
  143.         err = NewScrapbookFile(&fileToOpen, &cancelled);
  144.         if (err != noErr) goto error;
  145.     } else {
  146.         /* The caller specified a file */
  147.         fileToOpen = *sourceFile;
  148.     }
  149.     /* Open the file */
  150.     refNum = FSpOpenResFile(&fileToOpen, fsRdWrPerm);
  151.     if ((err = ResError()) != noErr) goto error;
  152.     UseResFile(refNum);
  153.     
  154.     /* Create a new window */
  155.     storage = NewPtrClear(sizeof(WindowRecord));
  156.     if (err = MemError()) goto error;
  157.     newWindow = GetNewCWindow(kDisplayWindow, storage, (WindowPtr)-1);
  158.     if (err = MemError()) goto error;
  159.     SetPort(newWindow);
  160.     
  161.     /* Create and initialize our window information block */
  162.     info = (wiHand)NewHandleClear(sizeof(WindowInfo));
  163.     if (err = MemError()) goto error;
  164.  
  165.     /* Define the area where each entry will be drawn */
  166.     drawingArea = newWindow->portRect;
  167.     drawingArea.bottom = drawingArea.bottom - 48;
  168.     InsetRect(&drawingArea, 11, 11);
  169.     (*info)->drawingArea = drawingArea;
  170.  
  171.     /* Define the area where the curr entry number, # of entries, */
  172.     /* and entry types will be drawn.                              */
  173.     statusArea = newWindow->portRect;
  174.     statusArea.top = statusArea.bottom - 32;
  175.     statusArea.bottom -= 6;
  176.     (*info)->statusArea = statusArea;
  177.     
  178.     (*info)->fRefNum = refNum;
  179.     (*info)->fileSpec = fileToOpen;
  180.     err = CountScrapbookEntries(&numEntries); 
  181.     if (err != noErr) goto error;
  182.     
  183.     /* Construct the scroll bar */
  184.     SetRect(&scrollBarBounds, 5, newWindow->portRect.bottom - 40, newWindow->portRect.right - 5, newWindow->portRect.bottom - 24);
  185.     /* Create a scroll bar with a minimum value of 1 and a max. value of numEntries */
  186.     /* If numEntries is 0, this would present a problem, except that the update      */
  187.     /* routine disables the scroll bar if numEntries == 0.                             */
  188.     scrollBar = NewControl(newWindow, &scrollBarBounds, "\p", true, 1, 1, numEntries, scrollBarProc, 0);
  189.     (*info)->selectionBar = scrollBar;
  190.     (*info)->numEntries = numEntries;
  191.     if (numEntries > 0) {
  192.         (*info)->currEntryNum = 1;            /* Select entry # 1 */
  193.         err = GetBestType(1, &scratchType);    /* Get the default type for entry 1 */
  194.         if (err != noErr) goto error;
  195.         (*info)->currEntryType = scratchType;
  196.     }
  197.     
  198.     /* Everything worked, so set up the window and display it */
  199.     SetWRefCon(newWindow, (long)info);
  200.     SetWTitle(newWindow, fileToOpen.name);
  201.     ShowWindow(newWindow);
  202.     DoUpdate(newWindow);
  203.     goto success;
  204.     
  205. error:
  206.     /* If there was a problem, then dispose of any allocated memory and close the file */
  207.     if (refNum > 0)
  208.         CloseResFile(refNum);
  209.     if (info != NULL)
  210.         DisposHandle((Handle)info);
  211.     if (newWindow != NULL)
  212.         CloseWindow(newWindow);
  213.     if (storage != NULL)
  214.         DisposPtr(storage);
  215.  
  216. success:
  217.     return err;
  218. } /* NewDisplayWindow */
  219.  
  220.  
  221. void CloseAWindow (WindowPtr whichWindow)
  222. {
  223.     short        wKind;
  224.     wiHand        info;
  225.  
  226.     if (whichWindow) {
  227.         wKind = ((WindowPeek)whichWindow)->windowKind;
  228.         if (wKind < 0)
  229.             CloseDeskAcc(wKind);
  230.         else if (wKind == userKind) {
  231.             info = (wiHand)GetWRefCon(whichWindow);
  232.             CloseResFile((*info)->fRefNum);
  233.             DisposHandle((Handle)info);
  234.             DisposeWindow(whichWindow);
  235.             AdjustMenus;
  236.         }
  237.     }
  238. } /* CloseAWindow */
  239.  
  240.  
  241. /*----------------------- Handle window update events ----------------------*/
  242.  
  243.  
  244. void DoUpdate (WindowPtr wp)
  245. {
  246.     Rect         updateRect;
  247.     wiHand        info = (wiHand)GetWRefCon(wp);
  248.     Rect        portRect = wp->portRect;
  249.     Rect        picRect;
  250.     RgnHandle    oldClip = NULL;
  251.     Rect        drawingArea, statusArea, drawingFrame, picFrame, scaledFrame;
  252.     ResType        resTypeList[10];
  253.     short        numResTypes, count;
  254.     OSErr        err;
  255.     Str255        scratchStr;
  256.     AEDesc        currItemDesc;
  257.     
  258.     SetPort(wp);                         /* make update window active grafPort    */
  259.     BeginUpdate(wp);                    /* visRgn temporarily = updateRgn        */
  260.     EraseRect(&portRect);
  261.     if ((*info)->numEntries == 0) 
  262.         HiliteControl((*info)->selectionBar, 255);
  263.     else
  264.         HiliteControl((*info)->selectionBar, 0);
  265.     DrawControls(wp);
  266.     
  267.     /* Get the areas of our window from the info record */
  268.     drawingArea = (*info)->drawingArea;
  269.     statusArea = (*info)->statusArea;
  270.  
  271.     /* Draw the nested boxs which bound the currently displayed entry */
  272.     PenNormal();
  273.     ForeColor(blackColor);
  274.     drawingFrame = drawingArea;
  275.     InsetRect(&drawingFrame, -1, -1);
  276.     PenSize(1, 1);
  277.     FrameRect(&drawingFrame);
  278.     InsetRect(&drawingFrame, -5, -5);
  279.     /* Draw the large frame in gray if we're de-activated */
  280.     if (((WindowPeek)wp)->hilited == 0)
  281.         PenPat(qd.gray);
  282.     ForeColor(blueColor);
  283.     PenSize(3, 3);
  284.     FrameRect(&drawingFrame);
  285.     ForeColor(blackColor);
  286.     PenNormal();
  287.     
  288.     /* remember our old clipping region so we can set the clip before drawing */
  289.     /* certain items */
  290.     oldClip = NewRgn();
  291.     GetClip(oldClip);
  292.     
  293.     
  294.     /* Draw the "number of items" statistic */
  295.     ClipRect(&statusArea);
  296.     TextFont(monaco); TextSize(9); TextFace(0);
  297.     MoveTo(statusArea.left, statusArea.bottom - 2);
  298.     NumToString((*info)->currEntryNum, scratchStr);
  299.     DrawString(scratchStr);
  300.     DrawString("\p / ");
  301.     NumToString((*info)->numEntries, scratchStr);
  302.     DrawString(scratchStr);
  303.     
  304.     /* Draw the list of resource types */
  305.     numResTypes = 10;
  306.     err = GetAllTypes((*info)->currEntryNum, &numResTypes, resTypeList);
  307.     if (err == noErr) {
  308.         /* Draw the list of types */
  309.         MoveTo(statusArea.right - numResTypes * StringWidth("\p      ") - 5, 
  310.                statusArea.bottom - 2);
  311.         for (count = 0; count < numResTypes; count++) {
  312.             OSTypeToPStr(resTypeList[count], (char *)scratchStr);
  313.             DrawString(scratchStr);
  314.             if (count < numResTypes - 1)
  315.                 DrawString("\p, ");
  316.         }
  317.     }
  318.     
  319.     
  320.     /* Draw the currently selected scrapbook entry */
  321.     ClipRect(&drawingArea);
  322.     err = Get1ScrapbookItem ((*info)->currEntryNum, (*info)->currEntryType, &currItemDesc);
  323.     if (err == noErr) {
  324.         if (currItemDesc.descriptorType == 'PICT') {
  325.             picFrame = (*(PicHandle)currItemDesc.dataHandle)->picFrame;
  326.             // <<< Create a properly scaled frame here
  327.             DrawPicture((PicHandle)currItemDesc.dataHandle, &drawingArea);
  328.         }
  329.         else if (currItemDesc.descriptorType == 'TEXT') {
  330.             MoveHHi(currItemDesc.dataHandle);
  331.             HLock(currItemDesc.dataHandle);
  332.             TextFont(times);
  333.             TextSize(0);
  334.             TextFace(0);
  335.             TextBox(*currItemDesc.dataHandle, GetHandleSize(currItemDesc.dataHandle), &drawingArea, teJustLeft);
  336.         }
  337.         else {
  338.             /* We don't know how to draw it */
  339.             MoveTo(drawingArea.left + 2, drawingArea.top + 18);
  340.             TextSize(12); TextFont(times); TextFace(bold);
  341.             DrawString("\pCannot display this entry");
  342.         }
  343.         (void) AEDisposeDesc(&currItemDesc);
  344.     }
  345.     
  346.     SetClip(oldClip);
  347.     DisposeRgn(oldClip);
  348.     
  349.     DrawControls(wp);
  350.     EndUpdate(wp);                        /* restore normal visRgn of grafport    */
  351. } /* DoUpdate */
  352.  
  353.  
  354. /* This is called whenever a window is activated or deactivated and is responsible */
  355. /* for highlighting (or dimming) the contents of the window appropriately.           */
  356. void DoActivate (WindowPtr wp, Boolean activate)
  357. {    
  358.     wiHand    info = (wiHand)GetWRefCon(wp);
  359.     
  360.     AdjustMenus();
  361.     SetPort(wp);
  362.     /* Highlight the selection bar appropriately */
  363.     if (activate && ((*info)->numEntries > 0))
  364.         HiliteControl((*info)->selectionBar, 0);
  365.     else
  366.         HiliteControl((*info)->selectionBar, 255);
  367.     /* Redraw the window so that the drawing area frame can be grayed out */
  368.     /* or highlighted.                                                      */
  369.     InvalRect(&wp->portRect);
  370.     DoUpdate(wp);
  371. } /* DoActivate */
  372.  
  373.  
  374. static pascal void ControlAction(ControlHandle whichControl, short part);
  375. /* Here's an action procedure which handles the case where the user */
  376. /* holds the mouse down in the selection scrollbar */
  377.  
  378. static pascal void ControlAction(ControlHandle whichControl, short part)
  379. {
  380.     short    value = GetCtlValue(whichControl);
  381.     
  382.     switch(part) {
  383.         case inUpButton:
  384.             value -= 1;
  385.         break;
  386.         
  387.         case inDownButton:
  388.             value += 1;
  389.         break;
  390.         
  391.         case inPageUp:
  392.             value -= 5;
  393.         break;
  394.         
  395.         case inPageDown:
  396.             value += 5;
  397.         break;
  398.         
  399.         default:
  400.             return;
  401.     }
  402.     
  403.     GoToEntry((*whichControl)->contrlOwner, value);
  404.     
  405. }
  406.  
  407.  
  408. void DoContentClick (WindowPtr whichWindow, Point globalPt)
  409. {
  410.     Point        localPt;
  411.     ControlHandle whichControl;
  412.     short        part;
  413.     wiHand        info;
  414.  
  415.     if (whichWindow != FrontWindow())
  416.         SelectWindow(whichWindow);
  417.     else {
  418.         SetPort(whichWindow);
  419.         localPt = globalPt;
  420.         GlobalToLocal(&localPt);
  421.         info = (wiHand)GetWRefCon(whichWindow);
  422.         
  423.         /* The only clicks that interest us are clicks in the selection scrollbar */
  424.         if (part = FindControl(localPt, whichWindow, &whichControl)) {
  425.             if (part == inThumb) {
  426.                 TrackControl(whichControl, localPt, NULL);
  427.                 GoToEntry(whichWindow, GetCtlValue(whichControl));
  428.             } else
  429.                 TrackControl(whichControl, localPt, ControlAction);
  430.             
  431.         }
  432.         
  433.     }
  434. } /* DoContentClick */
  435.  
  436.